Partition array into disjoint intervals [Next Array]¶
Time: O(N); Space: O(N); medium
Given an array A, partition it into two (contiguous) subarrays left and right so that: * Every element in left is less than or equal to every element in right. * left and right are non-empty. * left has the smallest possible size.
Return the length of left after such a partitioning. It is guaranteed that such a partitioning exists.
Example 1:
Input: A = [5,0,3,8,6]
Output: 3
Explanation:
left = [5,0,3], right = [8,6]
Example 2:
Input: A = [1,1,1,0,6,12]
Output: 4
Explanation:
left = [1,1,1,0], right = [6,12]
Notes:
2 <= A.length <= 30000
0 <= A[i] <= 10^6
It is guaranteed there is at least one way to partition A as described.
Intuition Instead of checking whether all(L <= R for L in left for R in right), let’s check whether max(left) <= min(right).
Algorithm Let’s try to find max(left) for subarrays left = A[:1], left = A[:2], left = A[:3], … etc. Specifically, maxleft[i] will be the maximum of subarray A[:i]. They are related to each other: max(A[:4]) = max(max(A[:3]), A[3]), so maxleft[4] = max(maxleft[3], A[3]).
Similarly, min(right) for every possible right can be found in linear time.
After we have a way to query max(left) and min(right) quickly, the solution is straightforward.
[1]:
class Solution1(object):
"""
Next Array
"""
def partitionDisjoint(self, A) -> int:
"""
:type A: List[int]
:rtype: int:
"""
N = len(A)
maxleft = [None] * N
minright = [None] * N
m = A[0]
for i in range(N):
m = max(m, A[i])
maxleft[i] = m
m = A[-1]
for i in range(N-1, -1, -1):
m = min(m, A[i])
minright[i] = m
for i in range(1, N):
if maxleft[i-1] <= minright[i]:
return i
[2]:
s = Solution1()
A = [5,0,3,8,6]
assert s.partitionDisjoint(A) == 3
A = [1,1,1,0,6,12]
assert s.partitionDisjoint(A) == 4
[3]:
class Solution2(object):
def partitionDisjoint(self, A):
"""
:type A: List[int]
:rtype: int
"""
B = A[:]
for i in reversed(range(len(A)-1)):
B[i] = min(B[i], B[i+1])
p_max = 0
for i in range(1, len(A)):
p_max = max(p_max, A[i-1])
if p_max <= B[i]:
return i
[4]:
s = Solution2()
A = [5,0,3,8,6]
assert s.partitionDisjoint(A) == 3
A = [1,1,1,0,6,12]
assert s.partitionDisjoint(A) == 4